How To: Prosty newsletter z użyciem Microsoft Flow i SharePoint Online
Table of Contents
Ten artykuł stanowi kontynuację opisywanych wcześniej rozwiązań tworzenia prostego newslettera korzystając z SharePoint Designer 2013, opisanego tutaj i drugiego, korzystając z Nintex Workflow dla Office 365, opisanego tutaj. Tym razem chciałbym pokażę, jak podobne rozwiązanie może zostać zbudowane korzystając z Microsoft Flow i SharePoint Online.
Przygotwania
Podobnie, jak miało to miejsce dla rozwiązań zbudowanych z użyciem SharePoint Designer i Nintex, aplikacja oparta została o dwie listy SharePoint, stworzone w dedykowanej Team Site:
- Newslettery, zbudowana z kolumn:
- Tytuł wiadomości (Title, tekst, wymagane)
- Treść wiadomości (Body, wiele linijek tekstu, włączona opcja formatowania HTML, wymagane)
- Skrzynka nadawcza, zbudowana z kolumn:
- Nazwa wysyłki/ kampanii (Title, tekst, wymagane)
- Odbiorcy SP (Recipients_SP, Osoba lub grupa, możliwe grupy, wielokrotny wybór)
- Odbiorcy Email (Recipients_EMAIL, wiele linijek tekstu, sam tekst)
- Data wysyłki (SendDate, data i czas, wymagane)
- Testowa wysyłka (TestDelivery, true/false)
- Wysłano (IsSent, true/false)
- Newsletter do wysłania (Newsletter, lookup do listy Newslettery, wymagane)
Workflow
Naturalnie, tworząc rozwiązanie na MS Flow starałem się maksymalnie wykorzystać podejście sprawdzone w rozwiązaniu Nintex. Szło całkiem nieźle, do chwili gdy zorientowałem się, że Flow posiada dość istotne ograniczenia. Fakt, że jest to rozwiązanie wciąż budowane i rozwijane, toteż te ograniczenia w skończonym czasie znikną (lista zmian jest dostępna tutaj).
Ograniczenia Flow i ich rozwiązania
- Problem: Nie byłem w stanie umieścić jednej pętli w drugiej. Osadzona pętla informowała mnie, że lista, która posiada elementy, jest pusta. Zastem nie byłem w stanie w jednej pętli pobrać wiadomości do wysłania, w drugiej zaś przejść listę odbiorców i wykonać akcję wysłania wiadomości.
Rozwiązanie: Stworzyłem drugi Flow, który był wołany przez „rodzica” i obsługiwał zdarzenie wysyłki wiadomości nietestowej. - Problem: Akcja w Flow, służąca do pobrania elementów z listy SharePoint nie obsługuje pól „Użytkownik lub grupa”, które posiadają wiele wartości lub, które umożliwiają wstawianie grup. Tak skonfigurowane pole po prostu nie jest dostępne wśród listy pól, z którymi można dalej pracować w procesie.
Rozwiązanie: Zmieniłem pole na „pojedynczy wybór” i zdecydowałem, by wszystkich dodatkowych odbiorców ręcznie wpisać w polu Recipients_EMAIL. - Problem: Nie byłem w stanie stworzyć połączenia dla usług Flow, przez co nie mogłem skorzystać z akcji „Start Flow”, by uruchomić drugi przepływ. Wciąż nie wiem, w czym tkwił problem.
Rozwiązanie: Użyłem akcji „HTTP” w celu wywołania drugiego przepływu, korzystając z publicznego adresu jego endpointa i żądania POST. - Problem: Nie można zadeklarować zmiennej gdziekolwiek. Można to zrobić wyłącznie na najwyższym poziomie definicji akcji.
Rozwiązanie: Zainicjowałem wyłącznie najbardziej wymagane zmienne. Dla pozostałych użyłem akcji „Compute” i dalej korzystałem z wyniku działania akcji.
Co mi się podoba w Flow?
Porównywanie Flow do Nintex dla Office 365 jest trudne i w zasadzie nie ma sensu. Bardziej celowe i właściwe byłoby porównanie go do Nintex Workflow Cloud (ale to planuję na później :)). W mojej ocenie to, co jest we Flow najbardziej użyteczne i praktyczne, to wyrażenia (wbudowane funkcje). W pojedynczej akcji, używając wielu wyrażeń, jestem w zasadzie w stanie wykonać wiele operacji i transformacji na danych, podczas gdy w Nintex dla Office 365, dla każdego operacji musiałbym praktycznie użyć oddzielnej akcji.
Kolejną rzeczą, która ułatwia pracę z Flow jest responsywność (chodzi mi o reagujący na szerokość okna interfejs responsive web design) – dzięki czemu korzystając z pokrętła na myszce i wciśniętego przycisku ctrl na klawiaturze, mogę pomniejszać i powiększa akcje na ekranie roboczym, mogąc zobaczyć cały proces.
Jak zbudowałem przepływy?
Poniżej umieściłem zrzuty ekranów obydwu przepływów, których używam w moim prostym newsletterze. Opisałem je w szczegółach poniżej.
Newsletter TimerJob Flow
To jest główny przepływ. Jego celem jest uruchamianie się w zadanym harmonogramie (co godzinę) i w każdym uruchomieniu sprawdzanie listy „Wysyłki”, na obecność istnienia elementów, których data wysłania (Delivery_On) jest starsza lub równa dacie bieżącej oraz, które nie są jeszcze wysłane (Is_Sent = nie):
- Pierwsze akcje mają na celu zainicjowanie ważnych parametrów przepływu, takich jak czy maile mogą być wysyłane do odbiorców zewnętrznych, jaka jest domena wewnętrzna, jaki jest adres bezwzględny witryny, w jakiej działa aplikacja i względny.
- Następnie proces odpytuje listę „Wysyłki” w SharePoint w celu pobrania elementów, które następnie będzie przetwarzać.
- Dla każdego elementu odpytuje listę „Newsletterów”, w celu pobrania tytułu i treści. Pobierając treść, jednocześnie wykonuje na niej transformacje, zamieniając adresy względne, na bezwzględne, używając poniższego wyrażenia:
replace(replace(body('Get_Newsletter_data')['Body'],concat('href="',variables('var_Site_Relative_URL_Str')), concat('href="',variables('var_Site_Absolute_URL_Str'))), concat('src="',variables('var_Site_Relative_URL_Str')), concat('src="',variables('var_Site_Absolute_URL_Str')))
- Następnie, w sytuacji gdy jest to wysyłka testowa, wysyła wiadomość do użytkownika, który dodał element na listę wysyłek. Na koniec ustawia element jako wysłany („Is_Sent” = yes).
- W sytuacji, gdy nie jest to wysyłka testowa, proces łączy listy odbiorców SP i EMAIL, a następnie przekształca je w listy i korzystając z wyrażenia „UNION” usuwa duplikaty:
union(outputs('Merge_them_with_SP_Recipients_and_split_using_'';'''), outputs('Merge_them_with_SP_Recipients_and_split_using_'';'''))
- Następnie tworzy ciąg znaków w formacie JSON, łącząc w całość Newsletter_ID, Outbox_ID, flagę, czy dopuszczona jest wysyłka do odbiorców zewn., listę odbiorców, tytuł i treść newslettera. Dwie ostatnie zmienne zostają dodatkowo zabezpieczone wyrażeniem „encodeUriComponent”, dzięki czemu mam pewność, że format JSON jest poprawny 🙂
- Następnie proces wykonuje akcję „HTTP”, wołając publiczny endpoint przepływu „Process newsletter delivery”, podając jako ciało żądania przygotowany w poprzednim kroku ciąg JSON.
- Finalnie zatrzymuje się, czekając na odpowiedź z drugiego przepływu. Gdy odpowiedź jest równa 200 oznacza element jako wysłany. W przeciwnym razie nie robi nic.
Process newsletter delivery
Celemn tego przepływu jest nic innego, jak odczytanie danych przekazanych jako inicjujące, zdekodowanie tytułu i treści newslettera (używając wyrażenia „decodeUriComponent”) i następnie, dla każdego odbiorcy z przekazanej listy, sprawdzanie, czy jest on zewnętrzny, czy wewnętrzny i w przypadku gdy jest zewnętrzny – czy posiada „zgodę” na dostarczenie mu wiadomości. Finalnie po prostu wysyła wiadomość. I tyle 🙂
REST endpoint drugiego przepływu pracy posiada następujący schemat:
{ "type": "object", "properties": { "newsletterID": { "type": "number" }, "outboxID": { "type": "number" }, "external_allowed": { "type": "boolean" }, "internal_domain": { "type": "string" }, "title": { "type": "string" }, "body": { "type": "string" }, "recipients": { "type": "array", "items": { "type": "string" } } } }
Dalszy rozwój rozwiązania
Możliwe, iż w najbliższym czasie istniejące rozwiązanie można będzie dodatkowo rozbudować o:
- Możliwość wyboru wielu odbiorców spośród użytkowników i grup SharePoint, jak to ma miejsce w Nintex i SP Designer;
- Osadzać obrazki bezpośrednio w treści maila – funkcjonalność niemożliwa do zrealizowania korzystając z SP Designer, jednak jak najbardziej realna z użyciem Flow (więcej o rozwiązaniu tutaj);
- Załączniki – możliwość dodawania wielu załączników, które będą wysyłane wraz z wiadomością.
Podoba Ci się to rozwiązanie? Zapraszam do dyskusji poniżej! 🙂